#!/usr/bin/env python
# -*-*- encoding: utf-8 -*-*-
#
# Copyright 2008 Håvard Gulldahl
# License: GPLv2

import sys, getpass, logging

import gdata.photos
import gdata.photos.service

__license__ = "GPLv2"
__author__ = "<havard@gulldahl.no>"
__version__ = "0.1"
__doc__ = """Copy one ore more picasaweb albums from one account to another.

Usage:
%s [-d] <from-account> <to-account>

The -d switch enables debug messages (Beware! This may reveal secrets.)
""" % sys.argv[0]

class quikalbum(object):
  titles = []
  ids = []
  checksums = []
  exifsums = []
  exifdates = []
  def __init__(self, album):
    for entry in album.entry:
      self.titles.append(entry.title.text)
      self.ids.append(entry.id.text)
      self.checksums.append(entry.checksum.text)
  def hasTitle(self, entry):
    return entry.title.text in self.titles
  def hasId(self, entry):
    return entry.id.text in self.ids
  def hasChecksum(self, entry):
    return entry.checksum.text in self.checksums

class copier(object):
  failed = []

  def __init__(self, _from, _to):
    self._from = _from
    self._to = _to
    self.frompicasa = gdata.photos.service.PhotosService(
        email=_from,
        password=getpass.getpass('Enter password for %s: ' % _from),
        source='lurtgjort.no-PicasaPush/albumcopy-0.1')
    self.frompicasa.ProgrammaticLogin()

    self.topicasa = gdata.photos.service.PhotosService(
        email=_to,
        password=getpass.getpass('Enter password for %s: ' % _to),
        source='lurtgjort.no-PicasaPush/albumcopy-0.1')
    self.topicasa.ProgrammaticLogin()

    self.fromalbums = self.frompicasa.GetUserFeed(kind='album')

  def copy(self, fromalbum=None):

    existingalbums = {}
    for e in self.topicasa.GetUserFeed(kind='album').entry:
      existingalbums[str(e.title.text)] = e

    print "Which album do you want to copy from %s to %s?" % (self._from, self._to)
    if fromalbum is not None:
      for i, z in enumerate(self.fromalbums.entry):
        if z.title.text == fromalbum:
          fromalbum = z
          break
    else:
      incomplete = dups = False
      for i, z in enumerate(self.fromalbums.entry):
        s = "%s: %s (%s photos)" % (i, z.title.text, z.numphotos.text)
        if existingalbums.has_key(z.title.text):
          if z.numphotos.text != existingalbums[z.title.text].numphotos.text:
            s += " ##"
            incomplete = True
          else:
            s += " **"
            dups = True
        print s
      if dups:
        print " **: This album already exists at the %s account." % self._to
      if incomplete:
        print " ##: This album already exists, but with a different photo count."
      fromalbum = self.fromalbums.entry[int(raw_input('Choose album: ').strip())]

    logging.debug("fromalbum: %s", fromalbum)

    toalbum = self.topicasa.Post(fromalbum, uri='/data/feed/api/user/%s' % self._to,
      converter=gdata.photos.AlbumEntryFromString)

    logging.debug("toalbum: %s", toalbum)
    logging.info("Created '%s' at %s", toalbum.title.text, self._to)

    fromphotos = self.frompicasa.GetFeed(fromalbum.GetPhotosUri())
    numphotos = len(fromphotos.entry)
    logging.info("About to copy %i images" % numphotos)

    self.failed = []

    for i, e in enumerate(fromphotos.entry):
      try:
        logging.debug("Copying photo %s, from url: %s", e.title.text, e.GetMediaURL())
        media = self.frompicasa.GetMedia(e.GetMediaURL())
        newphoto = self.topicasa.InsertPhoto(toalbum, e, media.file_handle)
        yield ( float(i+1)/float(numphotos), newphoto )
      except Exception, (err):
        logging.error("Copying %s FAILED: %s", e.title.text, str(err))
        self.failed.append(e)
    logging.info("The transfer of the '%s' album is finished." % fromalbum.title.text)
    if self.failed:
      logging.error("%i images failed:", len(self.failed))
      for photo in self.failed:
        logging.error("%s: %s", photo.title.text, photo.GetMediaURL())
      logging.debug("Programmers: Take a look at .failed[] to get the failed photos")

if __name__ == '__main__':
  DEBUG=False
  if "-d" in sys.argv:
    DEBUG=True
    sys.argv.remove('-d')

  if DEBUG:
    import httplib
    httplib.HTTPConnection.debuglevel=1  ## verbosely output http traffic
    logging.basicConfig(level=logging.DEBUG)
  else:
    logging.basicConfig(level=logging.INFO)

  try:
    copymachine = copier(sys.argv[1], sys.argv[2])
  except IndexError:
    logging.error("Required arguments missing")
    print __doc__
    sys.exit(1)
  cont = 'y' # run the loop at least once
  while(not 'n' in cont):
    for progress, photo in copymachine.copy():
      logging.info("%i%%: %s copied", progress*100, photo.title.text)
    cont = raw_input('Do you want to copy another album? [Y/n]').strip().lower()



